package com.htl.exampro.paper.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.htl.exampro.base.model.PageResult;
import com.htl.exampro.base.model.ServerResponse;
import com.htl.exampro.base.utils.UserUtil;
import com.htl.exampro.paper.mapper.PaperMapper;
import com.htl.exampro.paper.mapper.PaperQuestionMapper;
import com.htl.exampro.paper.pojo.domain.PaperDO;
import com.htl.exampro.paper.pojo.domain.PaperQuestionDO;
import com.htl.exampro.paper.pojo.query.PaperPageParam;
import com.htl.exampro.paper.pojo.vo.PaperQuestionVO;
import com.htl.exampro.paper.pojo.vo.PaperVO;
import com.htl.exampro.paper.service.PaperService;
import com.htl.exampro.question.api.QuestionApi;
import com.htl.exampro.question.pojo.vo.QuestionVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 试卷表 服务实现类
 * </p>
 *
 * @author hehehe
 * @since 2025-05-26
 */
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implements PaperService {
    @Autowired
    private PaperQuestionMapper paperQuestionMapper;

    @Autowired
    private QuestionApi questionApi;

    @Override
    public PaperVO queryPaperById(String paperId) {
        PaperDO paperDO = baseMapper.selectById(paperId);
        PaperVO paperVO = BeanUtil.toBean(paperDO, PaperVO.class);
        LambdaQueryWrapper<PaperQuestionDO> queryWrapper = Wrappers.lambdaQuery(PaperQuestionDO.class);
        queryWrapper.eq(PaperQuestionDO::getPaperId, paperId);
        List<PaperQuestionDO> paperQuestionDOS = paperQuestionMapper.selectList(queryWrapper);
        if(CollUtil.isEmpty(paperQuestionDOS)) {
            paperVO.setPaperQuestions(new ArrayList<>());
            paperVO.setTotalScore(0);
            paperVO.setQuestionCount(0);
            return paperVO;
        }
        List<Long> questionIds = paperQuestionDOS.stream().sorted(Comparator.comparingInt(PaperQuestionDO::getOrderby)).map(PaperQuestionDO::getQuestionId).collect(Collectors.toList());
        ServerResponse<List<QuestionVO>> response = questionApi.queryQuestionByIds(questionIds);
        List<QuestionVO> questionVOS = response.getResult();
        Map<String, QuestionVO> questionVOMap = questionVOS.stream().collect(Collectors.toMap(QuestionVO::getQuestionId, o -> o));
        List<PaperQuestionVO> paperQuestionVOS = BeanUtil.copyToList(paperQuestionDOS, PaperQuestionVO.class);
        paperQuestionVOS.forEach(o -> {
            o.setTypeId(questionVOMap.get(o.getQuestionId()).getTypeId());
            o.setContent(questionVOMap.get(o.getQuestionId()).getContent());
            o.setOptions(questionVOMap.get(o.getQuestionId()).getOptions());
            o.setAnswer(questionVOMap.get(o.getQuestionId()).getAnswer());
            o.setAnalysis(questionVOMap.get(o.getQuestionId()).getAnalysis());
            o.setDifficulty(questionVOMap.get(o.getQuestionId()).getDifficulty());
            o.setIsPublic(questionVOMap.get(o.getQuestionId()).getIsPublic());
            o.setIsCurrent(questionVOMap.get(o.getQuestionId()).getIsCurrent());
        });
        paperVO.setPaperQuestions(paperQuestionVOS);
        Integer score = paperQuestionDOS.stream().map(PaperQuestionDO::getScore).mapToInt(Integer::intValue).sum();
        paperVO.setTotalScore(score);
        paperVO.setQuestionCount(paperQuestionDOS.size());
        return paperVO;
    }

    @Override
    public PageResult<PaperVO> queryPaperPage(PaperPageParam pageParam) {
        Page<PaperDO> page = new Page<>(pageParam.getPageNumber(), pageParam.getPageSize());
        LambdaQueryWrapper<PaperDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PaperDO::getCreatedPerson, UserUtil.getUserId());
        queryWrapper.like(StringUtils.isNotBlank(pageParam.getPaperName()), PaperDO::getPaperName, pageParam.getPaperName());
        page(page, queryWrapper);
        PageResult<PaperVO> result = PageResult.result(page, PaperVO.class);
        result.getData().forEach(paperVO -> {
            LambdaQueryWrapper<PaperQuestionDO> queryWrapper1 = Wrappers.lambdaQuery(PaperQuestionDO.class);
            queryWrapper1.eq(PaperQuestionDO::getPaperId, paperVO.getPaperId());
            List<PaperQuestionDO> paperQuestionDOS = paperQuestionMapper.selectList(queryWrapper1);
            Integer score = paperQuestionDOS.stream().map(PaperQuestionDO::getScore).mapToInt(Integer::intValue).sum();
            paperVO.setTotalScore(score);
            paperVO.setQuestionCount(paperQuestionDOS.size());
        });
        return result;
    }

    @Override
    @Transactional
    public int savePaper(PaperVO paperVO) {
        PaperDO paperDO = BeanUtil.toBean(paperVO, PaperDO.class);
        int insert = this.baseMapper.insert(paperDO);
        List<PaperQuestionVO> questions = paperVO.getPaperQuestions();
        if (questions != null && !questions.isEmpty()) {
            for (int i = 0; i < questions.size(); i++) {
                questions.get(i).setPaperId(String.valueOf(paperDO.getPaperId()));
                questions.get(i).setOrderby(i);
            }
            List<PaperQuestionDO> paperQuestionDOS = BeanUtil.copyToList(questions, PaperQuestionDO.class);
            paperQuestionMapper.insert(paperQuestionDOS);
        }
        return insert;
    }

    @Override
    @Transactional
    public int updatePaper(PaperVO paperVO) {
        // 修改paper
        PaperDO paperDO = BeanUtil.toBean(paperVO, PaperDO.class);
        int num = baseMapper.updateById(paperDO);
        // 添加排序
        List<PaperQuestionVO> paperQuestions = paperVO.getPaperQuestions();
        List<PaperQuestionDO> paperQuestionDOS = BeanUtil.copyToList(paperQuestions, PaperQuestionDO.class);
        for (int i = 0; i < paperQuestionDOS.size(); i++)
            paperQuestionDOS.get(i).setOrderby(i);
        // 试卷中新增的题目插入表中
        List<PaperQuestionDO> newList = paperQuestionDOS.stream().filter(o -> o.getRelatedId() == null).toList();
        paperQuestionMapper.insert(newList);

        List<PaperQuestionDO> existList = paperQuestionDOS.stream().filter(o -> o.getRelatedId() != null).toList();
        //删除试卷中之前存在，新提交的题目集合中不存在的题目
        LambdaQueryWrapper<PaperQuestionDO> queryWrapper = Wrappers.lambdaQuery(PaperQuestionDO.class);
        queryWrapper.select(PaperQuestionDO::getRelatedId).eq(PaperQuestionDO::getPaperId, paperDO.getPaperId());
        List<PaperQuestionDO> dataPaperQuestionDOS = paperQuestionMapper.selectList(queryWrapper);
        List<PaperQuestionDO> list = dataPaperQuestionDOS.stream().filter(o -> existList.stream().noneMatch(o1 -> o.getRelatedId().equals(o1.getRelatedId()))).toList();
        paperQuestionMapper.deleteByIds(list);
        //修改试卷中原来的题目的排序
        paperQuestionMapper.updateList(existList);
        return num;
    }

}
